package org.andao.security.model;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.MapKey;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import org.andao.core.annotation.DeleteChild;
import org.andao.core.base.model.RootModel;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Where;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.userdetails.UserDetails;



/**
 * 系统用户模型. 实现了spring security UserDetails
 * {@link org.springframework.security.userdetails.UserDetails} 接口，便于将用户交个spring
 * security管理.
 * 
 * @author Marco.hu(hzg139@163.com)
 */

@Entity
@Table(name = "seewo_sys_users")
@Inheritance(strategy = InheritanceType.JOINED)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class User extends RootModel implements UserDetails {

	private static final long serialVersionUID = 533999380252969758L;

	@Column(name = "unitId", insertable = false, updatable = false)
	private String unitId;// 用户组织ID

	@Column(name = "username", nullable = false, unique = true,length=50)
	private String username;// 用户登录账号

	@Column(name = "cnname",length=50)
	private String cnName;// 用户中文名

	@Column(name = "userPassword")
	private String password;// 用户密码

	@Column(name = "ENABLED")
	private boolean enabled = true;// 是否允许

	@Transient
	private String enabledChar;

	@Column(name = "ACCOUTEXPIRED")
	private boolean accountNonExpired = true;// 账号是否过期

	@Column(name = "ACCOUTLOCKED")
	private boolean accountNonLocked = true;// 账号是否锁定


	@Column(name = "CREDENTIALSEXPIRED")
	private boolean credentialsNonExpired = true;// 账号证书是否过期

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "lastLoginTime")
	private Date lastLoginTime = new Date();// 最后登录时间

	@Column(name = "loginIp")
	private String loginIp;// 登录IP

	@Column(name = "showOrder")
	private Integer showOrder = 0;// 排序号

	@Column(name = "USERTYPE")
	private String userType;//用户类型 : student,teacher,manager

	//@Column(name = "ticket")
	@Transient
	private String ticket; //用户当前 ticket
	
	@Column(name = "photoURL")
	private String photoURL;
	
	@Transient
	private GrantedAuthority[] authorities;// 用户权限
		
	// 用户所在组织单位
	@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST,CascadeType.MERGE })
	@JoinColumn(name = "unitId")
	@Where(clause="isDeleted=0")
	private OrgUnit orgUnit;

	// 系统用户与角色关联 n:n
	@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
	@JoinTable(name = "seewo_sys_roleusers", joinColumns = { @JoinColumn(name = "userId") }, inverseJoinColumns = { @JoinColumn(name = "roleId") })
	@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
	@Where(clause="isDeleted=0")
	@DeleteChild(deleteable=false)
	private Set<Role> roles = new LinkedHashSet<Role>(0);


	@OneToMany(fetch = FetchType.EAGER, cascade = { CascadeType.ALL }, mappedBy = "user")
	@MapKey(name = "exCode")
	private Map<String, UserExtends> userExtends = new LinkedHashMap<String, UserExtends>(0);//用户扩展信息
	
	
	@Column(name="CUSTOMUSERNAME",length=50,unique=true)
	private String customUsername;//自定义登录账号
	
	@Transient
	private String userTopMenuIds;//用户左侧菜单
	
	@Transient
	private String userRightsIds;//用户权限ID集合
	
	@Transient
	private List<String> roleIds = new ArrayList<String>(0);//角色ID集合
	
	
	
	public List<String> getRoleIds() {
		return roleIds;
	}


	public void setRoleIds(List<String> roleIds) {
		this.roleIds = roleIds;
	}


	/**
	 * @return the userTopMenuIds
	 */
	public String getUserTopMenuIds() {
		return userTopMenuIds;
	}


	/**
	 * @param userTopMenuIds the userTopMenuIds to set
	 */
	public void setUserTopMenuIds(String userTopMenuIds) {
		this.userTopMenuIds = userTopMenuIds;
	}


	/**
	 * @return the userRightsIds
	 */
	public String getUserRightsIds() {
		return userRightsIds;
	}


	/**
	 * @param userRightsIds the userRightsIds to set
	 */
	public void setUserRightsIds(String userRightsIds) {
		this.userRightsIds = userRightsIds;
	}


	public String getCustomUsername() {
		return customUsername;
	}


	public void setCustomUsername(String customUsername) {
		this.customUsername = customUsername;
	}


	public UserExtends getPropertys(String key) {
		UserExtends property = userExtends.get(key);
		return property;
	}
	
	public Map<String, UserExtends> getUserExtends() {
		return userExtends;
	}

	public void setUserExtends(Map<String, UserExtends> userExtends) {
		this.userExtends = userExtends;
	}

	public boolean isAccountNonExpired() {
		return accountNonExpired;
	}

	public void setAccountNonExpired(boolean accountNonExpired) {
		this.accountNonExpired = accountNonExpired;
	}

	public boolean isAccountNonLocked() {
		return accountNonLocked;
	}

	public void setAccountNonLocked(boolean accountNonLocked) {
		this.accountNonLocked = accountNonLocked;
	}

	public boolean isCredentialsNonExpired() {
		return credentialsNonExpired;
	}

	public void setCredentialsNonExpired(boolean credentialsNonExpired) {
		this.credentialsNonExpired = credentialsNonExpired;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public Date getLastLoginTime() {
		return lastLoginTime;
	}

	public void setLastLoginTime(Date lastLoginTime) {
		this.lastLoginTime = lastLoginTime;
	}

	public String getLoginIp() {
		return loginIp;
	}

	public void setLoginIp(String loginIp) {
		this.loginIp = loginIp;
	}

	public OrgUnit getOrgUnit() {
		return orgUnit;
	}

	public void setOrgUnit(OrgUnit orgUnit) {
		this.orgUnit = orgUnit;
	}

	public boolean isEnabled() {
		return enabled;
	}

	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}

	

	public Integer getShowOrder() {
		return showOrder;
	}


	public void setShowOrder(Integer showOrder) {
		this.showOrder = showOrder;
	}


	public String getUnitId() {
		return unitId;
	}

	public void setUnitId(String unitId) {
		this.unitId = unitId;
	}

	public String getCnName() {
		return cnName;
	}

	public void setCnName(String cnName) {
		this.cnName = cnName;
	}

	public Set<Role> getRoles() {
		return roles;
	}

	public void setRoles(Set<Role> roles) {
		this.roles = roles;
	}

	public GrantedAuthority[] getAuthorities() {
		return authorities;
	}

	public void setAuthorities(GrantedAuthority[] authorities) {
		this.authorities = authorities;
	}

	public String getUserType() {
		return userType;
	}

	public void setUserType(String userType) {
		this.userType = userType;
	}

	@Override
	public String toString() {
		return "[" +getUsername()+ "] -> ["+userType+"]";
	}

	public String getEnabledChar() {
		if(isEnabled()) enabledChar="Y";
		else enabledChar="N";
		return enabledChar;
	}

	public void setEnabledChar(String enabledChar) {
		this.enabledChar = enabledChar;
		if(this.enabledChar.equalsIgnoreCase("Y")) setEnabled(true);
		else setEnabled(false);
	}

	/*public String getAccountNonExpiredChar() {
		if(!isAccountNonExpired()) accountNonExpiredChar="Y";
		else accountNonExpiredChar="N";
		return accountNonExpiredChar;
	}

	public void setAccountNonExpiredChar(String accountNonExpiredChar) {
		this.accountNonExpiredChar = accountNonExpiredChar;
		if(this.accountNonExpiredChar.equalsIgnoreCase("Y")) setAccountNonExpired(true);
		else setAccountNonExpired(false);
	}

	public String getAccountNonLockedChar() {
		if(!isAccountNonLocked()) accountNonLockedChar="Y";
		else accountNonLockedChar="N";
		return accountNonLockedChar;
	}

	public void setAccountNonLockedChar(String accountNonLockedChar) {
		this.accountNonLockedChar = accountNonLockedChar;
		if(this.accountNonLockedChar.equalsIgnoreCase("Y")) setAccountNonLocked(true);
		else setAccountNonLocked(false);
	}

	public String getCredentialsNonExpiredChar() {
		if(!isCredentialsNonExpired()) credentialsNonExpiredChar="Y";
		else credentialsNonExpiredChar="N";
		return credentialsNonExpiredChar;
	}

	public void setCredentialsNonExpiredChar(String credentialsNonExpiredChar) {
		this.credentialsNonExpiredChar = credentialsNonExpiredChar;
		if(this.credentialsNonExpiredChar.equalsIgnoreCase("Y")) setCredentialsNonExpired(true);
		else setCredentialsNonExpired(false);
	}*/

	public boolean isContainRole(String roleCode) {
		Set<Role> roles = getRoles();
		if (!roles.isEmpty()) {
			for (Role role : roles) {
				if (role.getRoleCode().equals(roleCode)) {
					return true;
				}
			}
		}
		return false;
	}


	public String getTicket() {
		return ticket;
	}


	public void setTicket(String ticket) {
		this.ticket = ticket;
	}

    public String getPhotoURL() {
        return photoURL;
    }


    public void setPhotoURL(String photoURL) {
        this.photoURL = photoURL;
    }
    
    
}